#ifndef _TOKENISER_H_
#define _TOKENISER_H_	


#include "Entry.h"
#include "Event.h"
#include "Task.h"
#include "CommonUtils.h"
#include <BotException.h>

#include <Entry.h>
#include <Event.h>
#include <Task.h>
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <stdio.h>
#include <qdatetime.h>
#include <qstring.h>
#include <QDebug>
#include <regex>

using namespace std;

class Tokeniser
{
private:
	enum TYPE_ENTRY{
		TYPE_NULL,
		TYPE_T,
		TYPE_E
	};
	static TYPE_ENTRY _currentType;
	static const string KEYWORD_AT;
	static const string KEYWORD_ON;
	static const string KEYWORD_BY;
	static const string KEYWORD_FROM;
	static const string KEYWORD_TO;

	static const string TYPE_TASK;
	static const string TYPE_EVENT;

	static const string TIME_NONE;
	static const string NUMBER_STRING;
	static const string SPACE;

	static const char* DATE_FORMAT_ARMY;
	static const char* DATE_FORMAT_DAY;
	static const char* DATE_FORMAT_SHORT1;
	static const char* DATE_FORMAT_SHORT2;

	static const char* DATE_TODAY;
	static const char* DATE_TOMORROW;
	
	static const char* TIME_FORMAT_12_HOUR1;
	static const char* TIME_FORMAT_12_HOUR2;
	static const char* TIME_FORMAT_24_HOUR_TYPE1;
	static const char* TIME_FORMAT_24_HOUR_TYPE2;
	
	static const char* CMD_FORMAT_QUOTE1;
	static const char* CMD_FORMAT_QUOTE2;

	static const char* CMD_FORMAT_FLOATING;
	static const char* CMD_FORMAT_DATE;
	static const char* CMD_FORMAT_DATETIME;
	static const char* CMD_FORMAT_TIME;
	static const char* CMD_FORMAT_TIMETIME;
	static const char* CMD_FORMAT_DATEDATE;
	static const char* CMD_FORMAT_DATETIMETIME;
	static const char* CMD_FORMAT_DATETIMEDATETIME;
	static const char* CMD_FORMAT_RELATIVEDAY;

	static const char* CMD_FORMAT_EDITNAME;
	static const char* CMD_FORMAT_EDITTIME;
	static const char* CMD_FORMAT_EDITDATE;
	static const char* CMD_FORMAT_DELETE;
	static const char* CMD_FORMAT_DISPLAY;
	static const char* CMD_FORMAT_SEARCH;
	static const char* CMD_FORMAT_REDO;
	static const char* CMD_FORMAT_UNDO;
	static const char* CMD_FORMAT_HELP;
	static const char* CMD_FORMAT_CLEAR;
	static const char* CMD_FORMAT_EXIT;
	static const char* CMD_FORMAT_DONE;

	static const QTime TIME_MIDNIGHT;
	static void validateEntry(Entry*);
	static bool isEmpty(string);


public:
	static bool checkFormat(string);

	//function extracts command from user input
	//pre-req: a string of user input
	//post-req: return string of command
	static CommonUtils::COMMAND_TYPE extractCommand(string&);

	//function extracts the line number of event/task to be deleted
	//pre-req: a string of user input
	//post-req: return line number only
	static int extractLineNum(string&);

	//function extracts the keyword for the search function
	//pre-req: a string of user input
	//post-req: return a string of key words
	static string extractKey(string&);

	//function checks if a string is in another string
	//pre-req: 2 strings to compare
	//post-req: return true if one string is in the other and false otherwise
	static bool isInString(string&, string);

	//function extracts the name of event/task (between command and time/date)
	//pre-req: user input and keyword
	//post-req: return string of name of task/event
	static string extractName(string&);

	//function extracts type of entry to display
	//pre-req: string of user input
	//post-req: return type of entry
	static string extractTypeToDisplay(string);

	//scan string first and call relevant function
	//pre-req: line of text
	//post-req: return entry of info
	static Entry* extractEntry(string&);

	//function extracts the date of event only
	//pre-req: string of user input
	//post-req: return QDate
	static QDate formatDate(string);

	static int checkNumOfKeyword(string&);

	static string extractRelativeDay(string&);

	static void extractAndPackage(string&, vector <string>&);

	static string checkDateOrTime(string);
	
	//function extracts the time of event/task input by user
	//pre-req: line of user input
	//post-req: return QTime
	static QTime formatTime(string);

	static vector<string> extractEntryToEdit(string&);

	static vector<string> splitToWords(string);

	static void extractTask(vector<string>, Entry*&);

	static void extractEvent(vector<string>, Entry*&);

	static string convertDateTimeToString(string);
};

#endif // !_TOKENISER_H_